﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.IO;

namespace Crocodoc.Examples
{
    class Program
    {
        /// <summary>
        /// YOUR Api Token. Fill it out and then run.
        /// </summary>
        public static string ApiToken = "INSERT TOKEN HERE";

        private static string _uploadedFileUUID;

        private static string _uploadedUrlUUID;

        static void Main(string[] args)
        {
            
            try
            {
                Crocodoc.ApiToken = ApiToken;

                UploadFileTest();

                UploadURLTest();

                WaitForProcessing();

                SessionTest();

                StatusTest();

                DocumentTest();

                ThumbnailTest();

                TextTest();

                ErrorUnauthorized();

                ErrorInvalidStatusUUID();

                ErrorInvalidFilter();

                ErrorDownloadDocumentUUID();

                DeleteTest(_uploadedFileUUID);

                DeleteTest(_uploadedUrlUUID);
            }
            catch (CrocodocException ex)
            {
                WriteCrocodocError(ex);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex);
                Console.ForegroundColor = ConsoleColor.White;
            }

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.WriteLine();
            Console.WriteLine(" Crocodoc DotNET Examples Completed");
            Console.WriteLine(" <<< press ENTER to continue >>>");
            Console.ReadLine();
        }

        public static void WriteHeader(string header)
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(header);
            Console.WriteLine("-------------------------------------");
            Console.ForegroundColor = ConsoleColor.Gray;
        }

        public static void WaitForProcessing()
        {
            bool continuePolling = true;
            Console.ForegroundColor = ConsoleColor.DarkGray;
            Console.WriteLine("Polling for DONE Statuses:");
            while (continuePolling)
            {
                Console.Write(".");
                var statuses = CrocodocDocument.Status(new string[] { _uploadedFileUUID, _uploadedUrlUUID });
                continuePolling = statuses.Any(status => status.Status == DocumentStatusCode.Processing || status.Status == DocumentStatusCode.Queued);
                Thread.Sleep(200);
            }
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine();
        }

        public static void DeleteTest(string uuid)
        {
            WriteHeader("Testing CrocodocDocument.Delete(\"" + uuid + "\"):");
            Console.WriteLine("Deleted?: " + CrocodocDocument.Delete(uuid));
        }

        public static void DocumentTest()
        {
            WriteHeader("Testing CrocodocDownload.Document():");
            byte[] doc = CrocodocDownload.Document(_uploadedUrlUUID);
            Console.WriteLine("Byte Array Length: " + doc.Length);
            Console.WriteLine();
        }

        public static void SessionTest()
        {
            WriteHeader("Testing CrocodocSession.Create() with UUID " + _uploadedFileUUID + ":");
            string sessionID = CrocodocSession.Create(_uploadedFileUUID);
            Console.WriteLine("SessionID Created: " + sessionID);
            Console.WriteLine();
        }

        public static void StatusTest()
        {
            WriteHeader("Testing CrocodocDocument.Status(string):");

            DocumentStatus status = CrocodocDocument.Status(_uploadedFileUUID);
            if (status != null)
            {
                Console.WriteLine("Status For " + status.UUID + ": " + status.Status);
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Status was null...");
                Console.ForegroundColor = ConsoleColor.Gray;
            }
            
            WriteHeader("Testing CrocodocDocument.Status(string[]):");
            DocumentStatus[] statuses = CrocodocDocument.Status(new string[] { _uploadedFileUUID, _uploadedUrlUUID });
            foreach (var stat in statuses)
            {
                Console.WriteLine("Status For " + stat.UUID + ": " + stat.Status);
            }
            Console.WriteLine();
        }

        public static void TextTest()
        {
            WriteHeader("Testing CrocodocDownload.Text():");
            try
            {
                Console.WriteLine("Text Length Downloaded: " + CrocodocDownload.Text(_uploadedFileUUID).Length);
            }
            catch (CrocodocException ex)
            {
                WriteCrocodocError(ex);
            }
            Console.WriteLine();
        }

        public static void ThumbnailTest()
        {
            WriteHeader("Testing CrocodocDownload.Thumbnail(uuid):");
            byte[] thumbnail = CrocodocDownload.Thumbnail(_uploadedUrlUUID);

            Console.WriteLine("Byte Array Length:" + thumbnail.Length);

            WriteHeader("Testing CrocodocDownload.Thumbnail(uuid, width, height):");
            byte[] largeThumb = CrocodocDownload.Thumbnail(_uploadedFileUUID, 200, 200);
            Console.WriteLine("Byte Array Length:" + largeThumb.Length);

            // Save the thumbnail to disk.
            // File.WriteAllBytes("Test_Thumbnail_200x200.png", largeThumb);

            Console.WriteLine();
        }

        public static void UploadFileTest()
        {
            WriteHeader("Testing CrocodocDocument.UploadFile():");
            UploadResult result = CrocodocDocument.UploadFile("form-w4.pdf");
            if (result.HasError)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("There was an error uploading: " + result.Error);
                Console.ForegroundColor = ConsoleColor.Gray;
            }
            else
            {
                _uploadedFileUUID = result.UUID;
                Console.WriteLine("Upload Successful - New Document ID: " + result.UUID);
            }
            Console.WriteLine();
        }

        public static void UploadURLTest()
        {
            WriteHeader("Testing CrocodocDocument.UploadUrl():");
            UploadResult result = CrocodocDocument.UploadUrl("http://web.crocodoc.com/files/test-simple.pdf");
            if (result.HasError)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("There was an error uploading: " + result.Error);
                Console.ForegroundColor = ConsoleColor.Gray;
            }
            else
            {
                _uploadedUrlUUID = result.UUID;
                Console.WriteLine("Upload Successful - New Document ID: " + result.UUID);
            }
            Console.WriteLine();
        }

        public static void WriteError(string error)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(error);
            Console.ForegroundColor = ConsoleColor.Gray;
        }

        public static void WriteCrocodocError(CrocodocException ex)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Error Message: " + ex.Message);
            Console.WriteLine("Status Code: " + ex.StatusCode);
            Console.WriteLine("Web Error: " + ex.WebError);
        }

        public static void ErrorUnauthorized()
        {
            WriteHeader("Testing Error Unauthorized (Invalid API Token):");
            string realToken = ApiToken;
            Crocodoc.ApiToken = "INVALID TOKEN HERE";
            try
            {
                CrocodocDocument.Status(_uploadedFileUUID);
            }
            catch (CrocodocException ex)
            {
                WriteCrocodocError(ex);
            }
            Crocodoc.ApiToken = realToken;
            Console.WriteLine();
        }

        public static void ErrorInvalidStatusUUID()
        {
            WriteHeader("Testing Error Status (Invalid UUID):");

            var status = CrocodocDocument.Status("invalid-uuid-token");
            WriteError("Status.Error: " + status.Error + " Status.Status: " + status.Status);

            Console.WriteLine();
        }

        public static void ErrorInvalidFilter()
        {
            WriteHeader("Testing Error Session (Invalid UUID):");
            try
            {
                string session = CrocodocSession.Create("...");
            }
            catch (CrocodocException ex)
            {
                WriteCrocodocError(ex);
            }
            Console.WriteLine();
        }

        public static void ErrorDownloadDocumentUUID()
        {
            WriteHeader("Testing Error Document (Invalid UUID):");
            try
            {
                CrocodocDownload.Document("...");
            }
            catch (CrocodocException ex)
            {
                WriteCrocodocError(ex);
            }
            Console.WriteLine();
        }
    }
}
